package com.alog.storage.net;

import java.io.File;
import java.io.Serializable;
import java.util.HashMap;
import android.content.Context;
import android.text.TextUtils;
import android.util.Log;
import com.alog.storage.Contants;
import com.alog.storage.R;
import com.alog.storage.domain.ResponseInfo;
import com.alog.storage.utils.CommonUtil;
import com.alog.storage.utils.SharedPrefUtil;

/**
 * 网络接口API类可继承此类
 */
public abstract class BaseAPI implements Connector.RequestCallback {
    protected final int FAILURE = -1;
    protected final int SUCCESS = 0;
    protected APICallback callback;
    protected Connector connector;
    protected Context context;

    public BaseAPI(Context context, APICallback callback) {
        this.callback = callback;
        this.context = context.getApplicationContext();
        connector = Connector.getConnector(this.context);
    }

    /**
     * get方式，子类直接调用此方法请求服务器数据
     *
     * @param apiId 接口编号
     * @param url   接口url
     */
    protected final void requestData(int apiId, String url) {
        connector.doGet(apiId, url, getHeaders(), this);
    }

    /**
     * post方式，子类直接调用此方法请求服务器数据
     *
     * @param apiId 接口编号
     * @param url   接口url
     * @param body  数据
     */
    protected final void requestData(int apiId, String url, byte[] body) {
        connector.doPost(apiId, url, getHeaders(), Connector.BODY_TYPE_DEFAULT, body, this);
    }

    /**
     * 子类直接调用此方法上传文件
     *
     * @param url  接口url
     * @param file 需上传的文件File对象
     */
    protected final void uploadFile(int apiId, String url, File file) {
        connector.doPostFile(apiId, url, getHeaders(), file, this);
    }

    private HashMap<String, String> getHeaders() {
        HashMap<String, String> headers = new HashMap<>();
        String sessionToken = SharedPrefUtil.getState(context, String.class, Contants.SESSION_TOKEN);
        if (!TextUtils.isEmpty(sessionToken)) {
            headers.put("SessionToken", sessionToken);
        }
        headers.put("ChannelId", "1");
        String appVersion = CommonUtil.getVersionName(context);
        if (!TextUtils.isEmpty(appVersion)) {
            headers.put("AppVersion", appVersion);
        }
        headers.put("Platform", "8");

        String pushToken = SharedPrefUtil.getState(context, String.class, "device_token");
        if (!TextUtils.isEmpty(pushToken)) {
            headers.put("DeviceToken", pushToken);
        }
        return headers;
    }

    /**
     * 子类重写此方法,解析服务器返回的数据: storagefind.data
     *
     * @param info 返回的信息
     * @return
     * @throws Exception
     */
    protected abstract <T> T parseData(ResponseInfo info) throws Exception;

    /**
     * 取消请求
     */
    public final void cancelRequest() {
        connector.cancel(this.getClass().getSimpleName());
    }

    @Override
    public final void onResponse(ResponseInfo resp) {
        boolean isEncrypt = resp.isEncrypt;
        if (callback != null) {
            try {
                byte[] respData = isEncrypt ? decrypt(resp.respData) : resp.respData;
                if (respData != null) {
                    resp.respData = respData;
                    resp = parseResponseInfo(resp);
                }
                Log.i("TAG", "onResponse code : " + resp.code);
                Log.i("TAG", "onResponse message : " + resp.message);
                Log.i("TAG", "onResponse data : " + resp.data);
                if (resp.code < 0) {
                    callback.onFailure(resp.apiId, resp.code, !TextUtils.isEmpty(resp.message) ? resp.message : context.getString(R.string.server_error));
                } else {
                    callback.onSuccess(resp.apiId, parseData(resp));
                }
            } catch (Exception e) {
                e.printStackTrace();
                callback.onFailure(resp.apiId, FAILURE, context.getString(R.string.server_error));
            }
        }
    }

    @Override
    public final void onErrorResponse(int apiId) {
        if (callback != null) {
            callback.onFailure(apiId, FAILURE, context.getString(R.string.server_error));
        }
    }

    private ResponseInfo parseResponseInfo(ResponseInfo resp) {
        ResponseInfo info = resp;
        if (resp.respData != null && resp.respData.length > 0) {
            //如果是ProtoBuf格式，在此转换

        }
        return info;
    }

    /**
     * 子类调此方法,对上传的数据进行加密
     *
     * @param srcData 待加密的数据
     * @return
     */
    protected final byte[] encrypt(byte[] srcData) {
        byte[] tarData = null;
        try {
            //加密数据

        } catch (Exception e) {
            e.printStackTrace();
        }
        return tarData;
    }

    private String getSecureKey(Context context) {
        return SharedPrefUtil.getState(context, String.class, Contants.SECURE_KEY);
    }

    /**
     * 子类调此方法,对获取到的数据进行解密
     *
     * @param srcData 待解密的数据
     * @return
     */
    protected final byte[] decrypt(byte[] srcData) {
        byte[] tarData = null;
        try {
            //解密数据

        } catch (Exception e) {
            e.printStackTrace();
        }
        return tarData;
    }

    /**
     * 由业务处理类实现, 用于回调
     *
     * @param <T> 回调返回的数据
     */
    public interface APICallback<T> extends Serializable {
        public void onSuccess(int apiId, T data);

        public void onFailure(int apiId, int code, String msg);
    }

}
